import axios, { AxiosRequestConfig } from "axios";

export const href = window.location.href.split("#")[0] + "#";

console.log(5, SYSTEM_GLOBAL.baseURL);

// 创建一个独立的axios实例
const service = axios.create({
  baseURL: SYSTEM_GLOBAL.baseURL,
  // 定义统一的请求头部
  headers: {},
  // 配置请求超时时间
  timeout: 30 * 1000,
  // 如果用的JSONP，可以配置此参数带上cookie凭证，如果是代理和CORS不用设置
  // withCredentials: true
});
// 请求拦截
service.interceptors.request.use((config: any) => {
  //  TODO:
  // config.headers.Authorization = "Bearer " + localStorage.getItem("bearerToken");
  return config;
});

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    // 如果返回的状态码为200，说明接口请求成功，可以正常拿到数据
    // 否则的话抛出错误
    if (response && response.status === 200) {
      // 未登录，或登录超时
      // if (response?.data?.code === 401) {
      //   window.location.href = "/#/login";
      //   return;
      // }
      return Promise.resolve(response);
    } else {
      return Promise.reject(response);
    }
  },
  (error) => {
    console.error(error);
    return Promise.reject(error.response);
  }
);

export default service;

export interface customOptions extends AxiosRequestConfig<any> {
  loading?: boolean;
  mock?: boolean;
  showError?: boolean; // 报错是否提示
  loadingtitle?: string; //等待提示内容
}
/** 统一处理提示信息的弹框 */
const Loading = {
  log: 0,
  number: 0,
  title: "",
  addOneLog() {
    Loading.number++;
  },
  removeOneLog() {
    Loading.number--;
  },
  mantle: "" as any,
};
Object.defineProperty(Loading, "number", {
  get() {
    return Loading.log;
  },
  set(newValue) {
    if (newValue > 0) {
      if (Loading.mantle) {
        Loading.mantle.destroy();
      }
      // Loading.mantle = Mantle();
      // openMessage({
      //   content: Loading.title,
      //   key: "axios_loading",
      //   duration: 0,
      //   type: "loading",
      // });
    } else if (newValue === 0) {
      // 请求已完成
      // message.destroy("axios_loading");
      // closeMessage("axios_loading");
      Loading.mantle?.destroy?.();
    }

    Loading.log = newValue;
  },
});

/**
 * 核心函数，可通过它处理一切请求数据，并做横向扩展
 * @param {url} 请求地址
 * @param {params} 请求参数
 * @param {method} 请求方法
 * @param {options} 配置项 报错时默认都会有提示信息 showError传false关闭提示
 * @param {isloading} 是否加载等待框 默认是
 */
export function request(
  url: string,
  params: any,
  method: string,
  options: customOptions = {}
) {
  // 请求前loading
  return new Promise<any>((resolve, reject) => {
    let data = {};
    const {
      loading = true,
      loadingtitle = "加载中",
      mock,
      showError = true,
      headers,
      ...rest
    } = options;
    const headersObg: any = headers || {};
    let axiosStart = Date.now(),
      axiosEnd = 0;
    Loading.title = loadingtitle;
    // get请求使用params字段
    if (["get", "delete"].includes(method)) data = { params };
    // post请求使用data字段
    if (["post", "put"].includes(method)) {
      // 默认 form-data
      headersObg["Content-Type"] = "multipart/form-data";
      data = { data: params };
    }

    // 超过100 ms的请求出现提示框
    const promiseLoad = new Promise((resolve) => {
      setTimeout(() => {
        const showAdd = loading && axiosStart - axiosEnd > 500;
        if (showAdd) {
          Loading.addOneLog();
        }
        resolve(showAdd);
      }, 100);
    });
    // const handleSearchDebounced = debounce(() => {
    //   // 在这里执行搜索逻辑
    //   promiseLoad;
    // }, 500);
    // const debouncedFunction = debounce(async (params) => {
    //   // 在这里执行 Promise 函数
    //   promiseLoad;
    //   // console.log(result);
    // }, 500);
    service({
      url,
      method,
      ...data,
      headers: headersObg,
      ...rest,
    })
      .then((res: any) => {
        axiosEnd = Date.now();
        const { token } = res.data;
        // if (token && url !== "/Project/Login/Login") saveToken(token);
        const result =
          token && url !== "/Project/Login/Login" ? res.data.data : res.data;
        const { code, result: msg } = result;
        if (res.status === 0 || res.status === 200) {
          // 登录失效
          if (code === 210) {
            window.location.href = "/#/login";
            return;
          }

          if (code === 230) {
            // openMessage({
            //   type: "error",
            //   content: msg || "报错",
            //   key: "disconnect-msg",
            // });
            setTimeout(() => {
              window.location.href = "/#/login";
            }, 2000);
            return;
          }

          if (code === 401 || code === 403) {
            // TODO:
            window.location.href = "/#/login";
            return;
            // onTokenOutTime(res);
            // reject(res);
          }
          // 接口返回捕获到问题
          if (code && code !== 200) {
            if (showError && code !== 401 && msg)
              // openMessage({
              //   type: "error",
              //   content: msg || "报错",
              // });
              reject(res);
          } else {
            resolve(result);
          }
        } else {
          // 通过配置可关闭错误提示
          if (showError && code !== 401 && msg)
            // openMessage({
            //   type: "error",
            //   content: msg || "报错",
            // });
            reject(res);
        }
      })
      .catch((err) => {
        if (err?.status === 401) location.href = "/#/login";
        // openMessage({
        //   type: "error",
        //   content: "操作失败",
        // });
        reject(err);
      })
      .finally(() => {
        promiseLoad.then((alreadyAdd) => {
          if (alreadyAdd) {
            Loading.removeOneLog();
          }
        });
      });
  });
}
// 封装GET请求
export function get(url: string, params: any = {}, options?: customOptions) {
  return request(url, params, "get", options);
}
// 封装POST请求
export function post(url: string, params: any = {}, options?: customOptions) {
  return request(url, params, "post", options);
}
// 封装PUT请求
export function put(url: string, params: any = {}, options?: customOptions) {
  return request(url, params, "put", options);
}
// 封装POST请求
export function deleteFn(
  url: string,
  params: any = {},
  options?: customOptions
) {
  return request(url, params, "delete", options);
}
